home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1999 March / EnigmA AMIGA RUN 35 (1999)(G.R. Edizioni)(IT)[!][issue 1999-03].iso / earcd / devel / vbcc-src / alias.c next >
C/C++ Source or Header  |  1999-01-01  |  12KB  |  311 lines

  1. /*  $VER: vbcc (alias.c) V0.4   */
  2. /*  Listen benutzter/veraenderter Variablen und Behandlung von Decknamen.   */
  3.  
  4. #include "opt.h"
  5.  
  6. static char FILE_[]=__FILE__;
  7.  
  8. int p_typ(struct Var *v)
  9. /*  Liefert den Typ, auf den Variable zeigen kann. Falls nicht eindeutig    */
  10. /*  wird CHAR zurueckgegeben, da ein char * auf alles zeigen kann.          */
  11. {
  12.     struct Typ *t=v->vtyp;int f;
  13.     /*  Kein Zeiger? Dann moeglicherweise Struktur, die verschiedene Zeiger */
  14.     /*  enthalten koennte. Koennte man evtl. noch genauer pruefen.          */
  15.     if((t->flags&NQ)!=POINTER||!t->next||(v->flags&DNOTTYPESAFE)) return(CHAR);
  16.     f=t->next->flags&NQ;
  17.     if(f==VOID) f=CHAR;
  18.     return(f);
  19. }
  20.  
  21. void ic_changes(struct IC *p,unsigned char *result)
  22. /*  Initialisiert den Bitvektor result mit allen Variablen, die durch das   */
  23. /*  IC p geaendert werden koennten.                                         */
  24. {
  25.     int i,j,t,t2;struct Var *v;
  26.     memset(result,0,vsize);
  27.     t=p->typf&NQ;
  28.     if(p->z.flags&VAR){
  29.         v=p->z.v;
  30.         i=v->index;
  31.         /*  Hilfsvariable, die waehrend diesem cse-Durchlauf eingefuehrt    */
  32.         /*  wurde.                                                          */
  33.         if(i<0) return;
  34.         if(p->z.flags&DREFOBJ) i+=vcount-rcount;
  35.         if(i>=vcount) ierror(0);
  36.         BSET(result,i);
  37.         /*  Wenn p geaendert wird, wird auch *p geaendert   */
  38.         if(i<rcount) BSET(result,i+vcount-rcount);
  39.  
  40.         if(p->z.flags&DREFOBJ){
  41.             if(noaliasopt){
  42.                 bvunite(result,av_drefs,vsize);
  43.                 bvunite(result,av_address,vsize);
  44.                 bvunite(result,av_globals,vsize);
  45.             }else{
  46.                 for(j=0;j<vcount-rcount;j++){
  47.                     v=vilist[j];
  48.                     if(!v) ierror(0);
  49.                     if(v->nesting==0||v->storage_class==EXTERN||(v->flags&USEDASADR)){
  50.                         struct Typ *tp=v->vtyp;
  51.                         if(!v->vtyp) ierror(0);
  52.                         do{
  53.                             t2=tp->flags&NQ;
  54.                             tp=tp->next;
  55.                         }while(t2==ARRAY);
  56.                         if(t==t2||t==CHAR||t2>POINTER){
  57.                             BSET(result,j);
  58.                             if(j<rcount) BSET(result,j+vcount-rcount);
  59.                             continue;
  60.                         }
  61.                     }
  62.                     if(j<rcount){
  63.                         t2=p_typ(v);
  64.                         if(t==t2||t==CHAR||t2==CHAR||t2>POINTER) BSET(result,j+vcount-rcount);
  65.                     }
  66.                 }
  67.             }
  68.         }else{
  69.             if(v->nesting==0||v->storage_class==EXTERN||(v->flags&USEDASADR)){
  70.                 if(noaliasopt){
  71.                     bvunite(result,av_drefs,vsize);
  72.                 }else{
  73.                     for(j=0;j<rcount;j++){
  74.                         t2=p_typ(vilist[j]);
  75.                         if(t==t2||t2==CHAR||t>POINTER) BSET(result,j+vcount-rcount);
  76.                     }
  77.                 }
  78.             }
  79.         }
  80.     }
  81.     if(p->code==CALL){
  82.         bvunite(result,av_drefs,vsize);
  83.         bvunite(result,av_address,vsize);
  84.         bvunite(result,av_globals,vsize);
  85.         bvunite(result,av_statics,vsize);
  86.     }
  87. }
  88. void ic_uses(struct IC *p,unsigned char *result)
  89. /*  Initialisiert den Bitvektor result mit allen Variablen, die durch das   */
  90. /*  IC p benutzt werden koennten.                                           */
  91. {
  92.     int i,j,t,t2,c;struct Var *v;struct Typ *tp;
  93.     memset(result,0,vsize);
  94.     c=p->code;t=p->typf&NQ;
  95.     if(c!=ADDRESS){
  96.         if((p->q1.flags&(VAR|VARADR))==VAR){
  97.             v=p->q1.v;
  98.             i=v->index;
  99.             if(c==ADDI2P||c==SUBIFP||c==SUBPFP) t=POINTER;
  100.             if(c==CONVCHAR||c==CONVUCHAR) t=CHAR;
  101.             if(c==CONVSHORT||c==CONVUSHORT) t=SHORT;
  102.             if(c==CONVINT||c==CONVUINT) t=INT;
  103.             if(c==CONVLONG||c==CONVULONG) t=LONG;
  104.             if(c==CONVFLOAT) t=FLOAT;
  105.             if(c==CONVDOUBLE) t=DOUBLE;
  106.             if(c==CONVPOINTER) t=POINTER;
  107.             if(i>=vcount) {pric2(stdout,p);ierror(0);}
  108.             BSET(result,i);
  109.             if(v->nesting==0||v->storage_class==EXTERN||(v->flags&USEDASADR)){
  110.                 if(noaliasopt){
  111.                     bvunite(result,av_drefs,vsize);
  112.                 }else{
  113.                     for(j=0;j<rcount;j++){
  114.                         t2=p_typ(vilist[j]);
  115.                         if(t==t2||t2==CHAR||t>POINTER) BSET(result,j+vcount-rcount);
  116.                     }
  117.                 }
  118.             }
  119.             if(p->q1.flags&DREFOBJ){
  120.                 BSET(result,i+vcount-rcount);
  121.                 if(noaliasopt){
  122.                     bvunite(result,av_drefs,vsize);
  123.                     bvunite(result,av_address,vsize);
  124.                     bvunite(result,av_globals,vsize);
  125.                 }else{
  126.                     for(j=0;j<vcount-rcount;j++){
  127.                         v=vilist[j];
  128.                         if(v->nesting==0||v->storage_class==EXTERN||(v->flags&USEDASADR)){
  129.                             tp=v->vtyp;
  130.                             do{
  131.                                 t2=tp->flags&NQ;
  132.                                 tp=tp->next;
  133.                             }while(t2==ARRAY);
  134.                             if(t==t2||t==CHAR||t2>POINTER||t>POINTER) BSET(result,j);
  135.                         }
  136.                         if(j<rcount){
  137.                             t2=p_typ(v);
  138.                             if(t==t2||t==CHAR||t2==CHAR||t>POINTER) BSET(result,j+vcount-rcount);
  139.                         }
  140.                     }
  141.                 }
  142.             }
  143.         }
  144.         if((p->q2.flags&(VAR|VARADR))==VAR){
  145.             v=p->q2.v;
  146.             i=v->index;
  147.             if(c==SUBPFP) t=POINTER;
  148.             if(i>=vcount) {pric2(stdout,p);ierror(0);}
  149.             BSET(result,i);
  150.             if(v->nesting==0||(v->flags&USEDASADR)){
  151.                 if(noaliasopt){
  152.                     bvunite(result,av_drefs,vsize);
  153.                 }else{
  154.                     for(j=0;j<rcount;j++){
  155.                         t2=p_typ(vilist[j]);
  156.                         if(t==t2||t2==CHAR||t>POINTER) BSET(result,j+vcount-rcount);
  157.                     }
  158.                 }
  159.             }
  160.             if(p->q2.flags&DREFOBJ){
  161.                 BSET(result,i+vcount-rcount);
  162.                 if(noaliasopt){
  163.                     bvunite(result,av_drefs,vsize);
  164.                     bvunite(result,av_address,vsize);
  165.                     bvunite(result,av_globals,vsize);
  166.                 }else{
  167.                     for(j=0;j<vcount-rcount;j++){
  168.                         v=vilist[j];
  169.                         if(v->nesting==0||v->storage_class==EXTERN||(v->flags&USEDASADR)){
  170.                             tp=v->vtyp;
  171.                             do{
  172.                                 t2=tp->flags&NQ;
  173.                                 tp=tp->next;
  174.                             }while(t2==ARRAY);
  175.                             if(t==t2||t==CHAR||t2>POINTER) BSET(result,j);
  176.                         }
  177.                         if(j<rcount){
  178.                             t2=p_typ(v);
  179.                             if(t==t2||t==CHAR||t2==CHAR) BSET(result,j+vcount-rcount);
  180.                         }
  181.                     }
  182.                 }
  183.             }
  184.         }
  185.     }
  186.     if((p->z.flags&(VAR|VARADR|DREFOBJ))==(VAR|DREFOBJ)){
  187.         v=p->z.v;
  188.         i=v->index;
  189.         if(i>=vcount) {pric2(stdout,p);ierror(0);}
  190.         BSET(result,i);
  191.         if(c==ADDI2P||c==SUBIFP) t=POINTER;
  192.         if(v->nesting==0||v->storage_class==EXTERN||(v->flags&USEDASADR)){
  193.             if(noaliasopt){
  194.                 bvunite(result,av_drefs,vsize);
  195.             }else{
  196.                 for(j=0;j<rcount;j++){
  197.                     t2=p_typ(vilist[j]);
  198.                     if(t==t2||t2==CHAR||t>POINTER||t2>POINTER) BSET(result,j+vcount-rcount);
  199.                 }
  200.             }
  201.         }
  202.     }
  203.     if(p->code==CALL){
  204.         bvunite(result,av_drefs,vsize);
  205.         bvunite(result,av_address,vsize);
  206.         bvunite(result,av_globals,vsize);
  207.         bvunite(result,av_statics,vsize);
  208.     }
  209. }
  210. void free_alias(struct flowgraph *fg)
  211. /*  Gibt alle use/change-Listen der ICs im Flussgraphen frei.               */
  212. {
  213.     struct IC *p;struct flowgraph *g;
  214.     if(DEBUG&1024) printf("freeing alias info\n");
  215.     for(g=fg;g;g=g->normalout){
  216.         for(p=g->start;p;p=p->next){
  217.             if(p->code==LABEL&&(p->use_cnt>0||p->change_cnt>0)) ierror(0);
  218.             if(p->use_cnt>0) free(p->use_list);
  219.             if(p->change_cnt>0) free(p->change_list);
  220.             if(p==g->end) break;
  221.         }
  222.     }
  223.     have_alias=0;
  224. }
  225. void create_alias(struct flowgraph *fg)
  226. /*  Initialisiert jedes IC mit einer Liste aller Variablen, die dadurch     */
  227. /*  benutzt und veraendert werden koennten. Z.Z. wird bis auf Typ-basierte  */
  228. /*  Optimierungen der worst-case angenommen.                                */
  229. {
  230.     unsigned char *vars=mymalloc(vsize);
  231.     struct IC *p;struct flowgraph *g;
  232.     int i,cnt;
  233.     if(DEBUG&1024) printf("creating alias info\n");
  234.     for(g=fg;g;g=g->normalout){
  235.         for(p=g->start;p;p=p->next){
  236.             ic_uses(p,vars);
  237.             for(i=0,cnt=0;i<vcount;i++)
  238.                 if(BTST(vars,i)) cnt++;
  239.             p->use_cnt=cnt;
  240.             if(cnt==0){
  241.                 p->use_list=0;
  242.             }else{
  243.                 p->use_list=mymalloc(cnt*VLS);
  244.                 for(cnt=0,i=0;i<vcount;i++){
  245.                     if(BTST(vars,i)){
  246.                         p->use_list[cnt].v=vilist[i];
  247.                         if(i>=vcount-rcount) p->use_list[cnt].flags=DREFOBJ;
  248.                                 else         p->use_list[cnt].flags=0;
  249.                         cnt++;
  250.                     }
  251.                 }
  252.             }
  253.             ic_changes(p,vars);
  254.             for(i=0,cnt=0;i<vcount;i++)
  255.                 if(BTST(vars,i)) cnt++;
  256.             p->change_cnt=cnt;
  257.             if(cnt==0){
  258.                 p->change_list=0;
  259.             }else{
  260.                 p->change_list=mymalloc(cnt*VLS);
  261.                 for(cnt=0,i=0;i<vcount;i++){
  262.                     if(BTST(vars,i)){
  263.                         p->change_list[cnt].v=vilist[i];
  264.                         if(i>=vcount-rcount) p->change_list[cnt].flags=DREFOBJ;
  265.                                 else         p->change_list[cnt].flags=0;
  266.                         cnt++;
  267.                     }
  268.                 }
  269.             }
  270.             if(p==g->end) break;
  271.         }
  272.     }
  273.     free(vars);
  274.     have_alias=1;
  275. }
  276. void update_alias(struct Var *old,struct Var *new)
  277. /*  Aendert alle use/changes von (old) auf (new). Wird aufgerufen, wenn     */
  278. /*  copy-propagation eine Variable neu zu einem DREFOBJ macht.              */
  279. {
  280.     struct IC *p;int i;
  281.     void *m;
  282.     if(DEBUG&1024) printf("update-alias\n");
  283.     for(p=first_ic;p;p=p->next){
  284.         for(i=0;i<p->use_cnt;i++){
  285.             if(p->use_list[i].v==old&&(p->use_list[i].flags&DREFOBJ)){
  286.                 m=p->use_list;
  287.                 p->use_cnt++;
  288.                 p->use_list=mymalloc(p->use_cnt*VLS);
  289.                 p->use_list[0].v=new;
  290.                 p->use_list[0].flags=DREFOBJ;
  291.                 memcpy(&p->use_list[1],m,(p->use_cnt-1)*VLS);
  292.                 free(m);
  293.                 break;
  294.             }
  295.         }
  296.         for(i=0;i<p->change_cnt;i++){
  297.             if(p->change_list[i].v==old&&(p->change_list[i].flags&DREFOBJ)){
  298.                 m=p->change_list;
  299.                 p->change_cnt++;
  300.                 p->change_list=mymalloc(p->change_cnt*VLS);
  301.                 p->change_list[0].v=new;
  302.                 p->change_list[0].flags=DREFOBJ;
  303.                 memcpy(&p->change_list[1],m,(p->change_cnt-1)*VLS);
  304.                 free(m);
  305.                 break;
  306.             }
  307.         }
  308.     }
  309. }
  310.  
  311.